import React, { Component } from 'react';
import { observable } from 'mobx';
import { observer , inject } from 'mobx-react';
import Util from "../lib/commonJs"
import Pop from "./Pop"
import { BaseApp } from "./BaseApp"
import $ from "jquery"
import { Input , Select , Button } from "antd"
import $config from "../../config"

const config = $config.config;

@inject('store') @observer
class Search extends BaseApp {

    constructor(props){
	super(props);
	this.searchType = [
	    {name:"blockHex",title:"区块哈希"},
	    {name:"blockHigh",title:"区块高度"},
	    {name:"txHex",title:"交易哈希"},
	];
	this.static = {
	    activeType:this.searchType[0].name // 0:通过高度查询区块详情 1:通过hex 查询区块详情 , 2:通过hex查询交易详情
	}
    }
    _showDetail =(value)=>{
	let _this = this;
	if(!Util.isEmpty(value)){
	    if(_this.static.activeType === "txHex"){
		PopTx(value,this.props.store.mainStore);
	    }else{
		PopBlock(value,_this.static.activeType==="blockHigh"?"high":_this.static.activeType==="blockHex"?"hex":"",this.props.store.mainStore);
	    }
	}
    };
    _onBlur =(event)=>{
	if(Util.isMobile()){
	    let value = event.currentTarget.value;
	    if(!Util.isEmpty(value)){
		this._showDetail(value)
	    }
	}
    };
    _onKeyUp = (event)=>{
	if(event.keyCode === 13){
	    let value = event.currentTarget.value;
	    if(!Util.isEmpty(value)) {
		$(event.currentTarget).trigger("blur");
		this._showDetail(value);
	    }
	}
    };
    _onClickSearch = ()=>{
	let val = $("#searchVal").val();
	if(!Util.isEmpty(val)){
	    this._showDetail(val);
	}
    };
    _choiceSearchType = (value)=>{
	this.static.activeType = value;
	$("#searchVal").focus().val("");
    };
    render() {
	return (
	    <div className="search-x-box">
		<div className="search-info">
		    <i className="fa fa-search" />
		    <div className="box-name">查询</div>
		    <div className="search-input-box">
			<div className={"head-search"}>
			    <div className={"search-box"}>
				<Input.Group compact>
				    <Select defaultValue={this.searchType[0].name} onChange={this._choiceSearchType}>
					{
					    this.searchType.map((n,i)=>{
					        return (
						    <Select.Option key={i} value={n.name}>{n.title}</Select.Option>
						)
					    })
					}
				    </Select>
				    <Input id="searchVal" style={{ width: '50%' }} onBlur={this._onBlur} onKeyUp={this._onKeyUp} />
				    <Button onClick={this._onClickSearch}>GO</Button>
				</Input.Group>
			    </div>
			</div>
		    </div>
		</div>
	    </div>
	)
    }
}
@inject('store') @observer
class Block extends BaseApp {

    constructor(props){
	super(props);

	this.static = {
	    blockShowData:["高度","交易","区块哈希","时间"]
	};
	this.state = {
	    blockList:[]
	}

    }
    _getBlockHigh = ()=>{
	let _this = this;
	const { store:{ mainStore:{ setBlockHigh } } } = this.props;
	return new Promise((resolve, reject)=>{
	    this.AJAX({
		type:"get",
		url:`${config.host}/getBlockHigh`,
		autoError:false,
	    }).then((data)=>{
		if(!Util.isEmpty(data)){
		    if(data.code === 200){
			setBlockHigh(data.data.count);
			resolve(data.data);
		    }else{
			Pop.alert(data.msg);
			reject(data.msg);
		    }
		}
	    })
	});
    };
    _getBlockList = ()=>{
	let _this = this;
	return new Promise((resolve, reject)=>{
	    this.AJAX({
		type:"get",
		url:`${config.host}/getBlockList`,
		autoError:false,
	    }).then((data)=>{
	        if(!Util.isEmpty(data)){
		    if(data.code === 200){
			_this.state.blockList = data.data;
			_this.setState(_this.state);
			resolve(data.data);
		    }else{
			Pop.alert(data.msg);
			reject(data.msg);
		    }
		}
	    })
	});
    };
    _getBlockByHigh = (event)=>{
	let value = $(event.currentTarget).find("span").text();
	PopBlock(value,"high",this.props.store);
    };
    _getBlockByHash = (event)=>{
	let value = $(event.currentTarget).find("span").text();
	PopBlock(value,"hex",this.props.store);
    };
    componentDidMount(){
	const { store:{ mainStore:{ setBlockHigh } } } = this.props;
	this._getBlockHigh().then((data)=>{
	    setBlockHigh(data.max);
	});
	this._getBlockList();
    }

    render() {

        const { store:{ mainStore:{ blockHigh } } } = this.props;

	return (
	    <div className="block-box">
		<div className="box-head">
		    <div className="box-name"><i className="fa fa-cubes" />区块</div>
		    <div className="box-value">{blockHigh}</div>
		</div>
		<div className="box-body">
		    <table className="theme-table block-table">
			<thead><tr>
			    {
				this.static.blockShowData.map((n,i)=>{
				    return ( <th key={i}>{n}</th> )
				})
			    }
			</tr></thead>
			<tbody>
			{
			    !Util.isEmpty(this.state.blockList)?this.state.blockList.map((n,i)=>{
				return(
				    <tr key={i}>
					<td>
					    <div className="cos-a" onClick={this._getBlockByHigh}><span>{n.height}</span></div>
					</td>
					<td>{n.tx_count}</td>
					<td>
					    <div className="cos-a" onClick={this._getBlockByHash}><span>{n.block_hash}</span></div>
					</td>
					<td className="table-time-column">{Util.timeFormat(new Date(parseInt(n.create_time)),"yyyy-MM-dd hh:mm")}</td>
				    </tr>
				)
			    }):this.StaticDom.emptyTr(4)
			}
			</tbody>
		    </table>
		</div>
	    </div>
	)
    }
}
@inject('store') @observer
class Peer extends BaseApp {


    constructor(props){
	super(props);
    }

    render() {
	return (
	    <div className="peer-box">
		<div className="peer-info">
		    <i className="fa fa-share-alt" />
		    <div className="box-name">节点数</div>
		    <div className="peer-num">&nbsp;&nbsp;{this.props.store.peerList.length}</div>
		</div>
	    </div>
	);
    }
}
@inject('store') @observer
class Transaction extends BaseApp {

    @observable txList = [];

    constructor(props){
	super(props);
	// this._init();
	/*this.settings = {
	    GET_TX_TIME:this.Static.GET_TX_TIME,        //循环获取交易的间隔时间
	    SHOW_TX_LIST:this.Static.SHOW_TX_LIST       //显示交易条数
	}*/

	this.settings = this.props.store.mainStore.setting;

	/*this.txList = [{
	    txId:"77abca7b86e8d286d6287b6544c392b85c3db281d37e1faba155627c4935cb2e",
	    createTime:"2018-03-13"
	},{
	    txId:"0e24314f253a11f206a666ac1677a6a2cbe25986c0a8299fdce69073b59ecad6",
	    createTime:"2018-03-10"
	},{
	    txId:"5a576e32163b53a22255d4c5b67ba414c8bf2b5a1b404949a2df7e7dec017f63",
	    createTime:"2018-03-10"
	},{
	    txId:"ab42f5be4872bdb3f7fc7caee8fb4a5ce381f558681221a0c4642388860aec92",
	    createTime:"2018-03-10"
	},{
	    txId:"a1f3c3a4cbdaaf96d04902d96711bc738600da842d0a62364344d0a555fabb4c",
	    createTime:"2018-03-05"
	},{
	    txId:"9d5f1d37c883607ae6a6810cee6c00a5231a857a0f7e6f7a0d77ab77cd9b0313",
	    createTime:"2018-03-05"
	},]*/

    }
    /*    _init = ()=>{
	    let _this = this;
	    let initGetting = setInterval(()=>{
		console.log("计数君");
		if(_this.txIdList.length > 0){
		    clearInterval(initGetting);
		    this._getTxList(_this.txIdList,0,(success)=>{
			_this.txList = success;
			// _this._cyclicGetTx();
		    })
		}
	    },300);
	    setTimeout(()=>{
		clearInterval(initGetting);
	    },20000);
	};

	_cyclicGetTx = ()=>{
	    let _this = this;
	    let _a = setInterval(()=>{
		this._getTxList(_this.txIdList,0,(success)=>{
		    _this.txList = success
		},(error)=>{
		    clearInterval(_a);
		})
	    },_this.settings.GET_TX_TIME);
	    return _a;
	};

	_getTxList = (idList,index,callback,error)=>{
	    let _this = this;
	    let _list = [];
	    let _a = (_idList,_index,_callback,_error)=>{
		_this._getTransactionById(_idList[_index]).then((data)=>{
		    _list.push({
			txId:data.txIdString,
			createTime:_this.Util.timeFormat(new Date(parseFloat(data.txTimestampString)),"yyyy-MM-dd hh:mm"),
		    });
		    if((_index+1) >= idList.length || (_index+1) === _this.settings.SHOW_TX_LIST){
			_callback(_list);
		    }else{
			_a(_idList,_index+1,_callback,_error)
		    }
		},(err)=>{
		    typeof _error !== "undefined"?_error(err):"";
		})
	    };
	    _a(idList,index,callback,error)
	};

	_getTransactionById = (txId)=>{
	    return new Promise((success,error)=>{
		this.AJAX({
		    type:"get",
		    url:`${this.serverHost}/QueryTransaction`,
		    data:{
			txId:txId
		    }
		}).then((data)=>{
		    if(data.state === 200){
			success(data.data)
		    }else{
			error(data.message)
		    }
		},(err)=>{
		    error(err)
		})
	    })
	};
    */
    _getTx = (data,e)=>{
	PopTx(data,this.props.store.mainStore);
    };
    _getTxList = ()=>{
	let _this = this;
	return new Promise((resolve, reject)=>{
	    this.AJAX({
		type:"get",
		url:`${this.props.store.mainStore.serverHost}/getTxList`,
		autoError:false,
	    }).then((data)=>{
		if(data.code === 200){
		    _this.txList = data.data;
		    resolve(data.data);
		}else{
		    Pop.alert(data.msg);
		    reject(data.msg);
		}
	    })
	});
    };
    componentDidMount(){
	this._getTxList();
    }
    render() {
	return (
	    <div className="tx-box">
		<div className="box-head">
		    <div className="box-name"><i className="fa fa-exchange" />交易</div>
		</div>
		<div className="box-body">
		    <table className="theme-table tx-table">
			<thead><tr>
			    <th>哈希</th>
			    <th className="table-time-column">时间</th>
			</tr></thead>
			<tbody>
			{
			    this.txList.length > 0 ? this.txList.map((n,i)=>{
				return(
				    <tr key={i} onClick={this._getTx.bind(this,n.transactionHash)}>
					<td className="ellipsis">{n.transactionHash}</td>
					<td>{Util.timeFormat(new Date(n.createTime),"yyyy-MM-dd hh:mm")}</td>
				    </tr>
				)
			    }):this.StaticDom.emptyTr(2)
			}
			</tbody>
		    </table>
		</div>
	    </div>
	);
    }
}
@inject('store') @observer
class PeerList extends BaseApp {
    constructor(props){
	super(props);
	this.peerList = [{
	    ip:"10.1.4.201",
	    state:1 // 宕机：0，正常1
	}];
    }
    _toPeerDetail = (event)=>{
	$(event.currentTarget).find("a")[0].click();
    };
    componentDidMount(){
	let _this = this;
	this.AJAX({
	    type:"get",
	    url:`${this.props.store.mainStore.serverHost}/getPeerList`,
	    autoError:false,
	}).then((data)=>{
	    if(data.code === 200){
		_this.props.store.mainStore.peerList = data.data;
	    }
	})
    }
    render() {
	return (
	    <div className="peerList-box">
		<div className="box-head">
		    <div className="box-name"><i className="fa fa-exchange" />节点列表</div>
		    <div className="box-value">{this.props.store.mainStore.peerList.length}</div>
		</div>
		<div className="box-body">
		    <table className="theme-table peerList-table">
			<thead>
			<tr>
			    <th>节点IP</th>
			    <th className="table-health-column">健康状态</th>
			</tr>
			</thead>
			<tbody>
			{
			    this.props.store.mainStore.peerList.length > 0 ? this.props.store.mainStore.peerList.map((n,i)=>{
				return(
				    <tr key={i} >{/* onClick={this._toPeerDetail}*/}
					<td className="ellipsis">{n.ip}</td>
					<td>
					    { PeerState(n.state) }
					    {/*<Link href={{pathname: '/peerDetail', query:n}}><a/></Link>*/}
					</td>
				    </tr>
				)
			    }):this.StaticDom.emptyTr(2)
			}
			</tbody>
		    </table>
		</div>
	    </div>
	);
    }
}
@inject('store') @observer
class BlockDetail extends BaseApp {

    @observable blockInfo = {
	high:0,
	txCount:0,
	dataCount:0,
	createTime:0,
	hex:0,
	pHex:0,
	txList:[],
    };

    constructor(props){
	super(props);
	let value = this.props.para.value;
	let searchType = this.props.para.searchType;
	this.getUrl = {
	    high:"getBlockInfoByHigh",
	    hex:"getBlockInfoByHex"
	};
	this._doAjax(searchType,value);
    }
    _openTx = (event)=>{
	PopTx($(event.currentTarget).text(),this.props.store.mainStore);
    };
    _changeBlock = (event)=>{
	let value = $(event.currentTarget).text();
	this._doAjax("hex",value);
    };
    _doAjax =(searchType,value)=>{
	let _this = this;
	_this.AJAX({
	    type:"post",
	    url:`${config.host}/${_this.getUrl[searchType]}`,
	    data:{
		value:value
	    }
	}).then((data)=>{
	    if(data.code === 200 && !Util.isEmpty(data.data)){
		this.blockInfo = {
		    high:data.data.height,
		    txCount:data.data.tx_count,
		    dataCount:data.data.sizeString,
		    createTime:Util.timeFormat(new Date(parseFloat(data.data.create_time)),"yyyy-MM-dd hh:mm"),
		    hex:data.data.block_hash,
		    pHex:data.data.previous_hash,
		    txList:JSON.parse(data.data.tx_list),
		}
	    }
	})
    };

    render() {
	return (
	    <div className="block-detail-box">
		<table className="theme-table block-detail-table">
		    <tbody>
		    <tr><td>区块高度</td><td>{this.blockInfo.high}</td></tr>
		    <tr><td>交易数量</td><td>{this.blockInfo.txCount}</td></tr>
		    {/*<tr><td>数据大小</td><td>{this.blockInfo.dataCount}</td></tr>*/}
		    <tr><td>生成时间</td><td>{this.blockInfo.createTime}</td></tr>
		    <tr><td>哈希</td><td>{this.blockInfo.hex}</td></tr>
		    <tr><td>前置区块哈希</td><td><div className="cos-a"><span onClick={this._changeBlock}>{this.blockInfo.pHex}</span></div></td></tr>
		    <tr><td>交易列</td><td>
			{
			    this.blockInfo.txList.map((n,i)=>{
				return (
				    <p className="cos-a" style={{margin:"5px 0"}} key={i}>
					<span onClick={this._openTx}>{n}</span>
				    </p>
				)
			    })
			}
		    </td></tr>
		    </tbody>
		</table>
	    </div>
	);
    }
}
@inject('store') @observer
class TxDetail extends BaseApp {

    constructor(props){
	super(props);

	this.state = {
	    txInfo:{
		hex:"",
		time:"",
		data:[]
	    },
	    _decode:this.props._decode
	};

    }
    _init = (txHex)=>{
	let _this = this;
	if(!Util.isEmpty(txHex)){
	    _this.AJAX({
		type:"post",
		url:`${config.host}/getTxInfo`,
		data:{
		    txHex:txHex
		},
		autoError:false
	    }).then((data)=>{
		if(data.code === 200 && !Util.isEmpty(data.data)){
		    _this.state.txInfo = {
			hex:data.data.transactionHash,
			time:Util.timeFormat(new Date(data.data.createTime),"yyyy-MM-dd hh:mm"),
			data:Util.isEmpty(data.data.smartContractArgs)?"":data.data.smartContractArgs
		    };
		    _this.setState(_this.state);
		}else{
		    Pop.alert(`获取交易失败：${data.msg}`)
		}
	    })
	}else{
	    Pop.alert("交易哈希不可为空")
	}
    };

    componentDidMount(){
	this._init(this.props.txId);
    }

    render() {

        const { txInfo:{ hex , time , data } } = this.state;

	return (
	    <div className="block-detail-box">
		<table className="theme-table tx-detail-table">
		    <tbody>
		    <tr><td>交易哈希</td><td>{hex}</td></tr>
		    <tr><td>生成时间</td><td>{time}</td></tr>
		    <tr><td /><td /></tr>
		    {
			!Util.isEmpty(data)?data.map((n,i)=>{
			    return (
				<tr key={i}><td>{i===0?'详细':''}</td><td>{Util.Base64.decode(n)}</td></tr>
			    )
			}):<tr/>
		    }
		    </tbody>
		</table>
	    </div>
	);
    }
}

const PeerState = (state)=>{
    return(
	<div className="peer-state" style={{backgroundColor:(state===0 || state==="0")?"red":"#449d44"}}/>
    )
};
const PopBlock = (value,searchType,store)=>{
    Pop.dialog({
	title:"区块详情",
	showOk:false,
	cancelText:"关闭",
	width:"600px",
	maxWidth:"calc(100% - 5px)",
	content:<BlockDetail para={{
	    searchType:searchType,//high,hex
	    value:value
	}} store={store} />
    })
};
const PopTx = (txId,store)=>{
    Pop.dialog({
	title:"交易详情",
	showOk:false,
	cancelText:"关闭",
	width:"570px",
	content:<TxDetail txId={txId} store={store} />
    })
};

@inject('store') @observer
class Overview extends BaseApp {
    constructor(props) {
	super(props);
    }
    render() {
	return (
	    <div>
		<Search/>
		<Block/>
		<Transaction/>
		<PeerList/>
	    </div>
	)
    }
}

export { Search , Peer , Block , Transaction , PeerList , BlockDetail , TxDetail , PeerState };
export default Overview;
